package de.playmee.geo;


import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Paint.Style;
import android.view.MotionEvent;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

public class RadiusOverlay extends Overlay {
	public static String TAG = "RadiusOverlay";
	
	// drawing data
	private BubbleOverlay bubbleOverlay;
	private Region region;
	
	// paint of circle
	private static Paint innerPaint = new Paint();
	private static Paint borderPaint = new Paint();
	
	private boolean touchedBubble = false, touchedCircle = false, moveable = false, drawTitle = false;
	
	static {
		innerPaint.setARGB(75, 75, 75, 75);
		innerPaint.setAntiAlias(true);
		innerPaint.setStyle(Paint.Style.FILL);
		
		borderPaint.setARGB(255, 75, 75, 75);
		borderPaint.setAntiAlias(true);
		borderPaint.setStyle(Style.STROKE);
		borderPaint.setStrokeWidth(2);;
	}
	
	public RadiusOverlay(Region region, Bitmap bubble) {
		this.region = region;
		this.bubbleOverlay = new BubbleOverlay(bubble);
	}
	
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		super.draw(canvas, mapView, shadow);
		// compute screen data (radius from meters to pixel, 
		//	center point from GeoPoint to screen coordinates)
		Projection projection = mapView.getProjection();
		int r = getRadius(region.getMeters(), projection);
		Point p = new Point();
		projection.toPixels(region.getCenter(), p);		

		// draw circle
		canvas.drawCircle(p.x, p.y, r, innerPaint);
		canvas.drawCircle(p.x, p.y, r, borderPaint);
		
		this.bubbleOverlay.draw(region.getTitle(), region.getCenter(), canvas, mapView, shadow);
	}
	
	public boolean onTouchEvent(MotionEvent event, MapView mapView) {
		boolean res = false;
		// get GeoPoint by screen coordinates
		GeoPoint hitPoint = mapView.getProjection().fromPixels((int)event.getX(), (int)event.getY());
		switch(event.getAction()) {
		case MotionEvent.ACTION_MOVE:
			// if the circle can moved (bubble is touched and edit mode is active)
			if (touchedBubble && moveable) {
				region.setCenter(hitPoint);
				res = true;
			}
			break;
		case MotionEvent.ACTION_DOWN:
			// check if circle, bubble are touched
			touchedCircle = isHitCircle(hitPoint, mapView);
			touchedBubble = bubbleOverlay.isHitBubble(hitPoint, mapView);
			break;
		case MotionEvent.ACTION_UP:
			// toggle text box
			if (touchedCircle && isHitCircle(hitPoint, mapView)){
				drawTitle = !drawTitle;
				bubbleOverlay.setDrawLabel(drawTitle());
				res = true;
			}
			touchedBubble = false;
			touchedCircle = false;
			break;
		}
		return res;
	}	
	
	/**
	 * computes if the given hit point intersects the circle
	 * @param hit
	 * @param mapView
	 * @return true, if hit intersects this circle
	 */
	private boolean isHitCircle(GeoPoint hit, MapView mapView) {
		return region.isOnThisRegion((float)(hit.getLatitudeE6()/1E6), (float)(hit.getLongitudeE6()/1E6));
	}
	
	/**
	 * computes the radius in pixels by the given radius in meters
	 * @param meters
	 * @param projection
	 * @return radius in pixels
	 */
	private int getRadius(float meters, Projection projection) {
		 return (int) (projection.metersToEquatorPixels(meters) * (1/ Math.cos(Math.toRadians(region.getCenter().getLatitudeE6()/1E6))));
	}
	
	
	public Region getRegion() {
		return region;
	}
	
	public boolean drawTitle() {
		return (moveable || drawTitle);
	}

	public boolean isMoveable() {
		return moveable;
	}

	public void setMoveable(boolean moveable) {
		this.moveable = moveable;
		bubbleOverlay.setDrawLabel(moveable || drawTitle);
	}
	
	public BubbleOverlay getBubbleOverlay() {
		return bubbleOverlay;
	}
	
	public void setBubbleOverlay(BubbleOverlay bOverlay) {
		bubbleOverlay = bOverlay;
	}
}
